package org.jupiter.blog.service.service.impl;

import org.jupiter.blog.api.convertor.JupiterUserRoleStructConvertor;
import org.jupiter.blog.api.domain.JupiterUserRole;
import org.jupiter.blog.api.dto.JupiterUserRoleDTO;
import org.jupiter.blog.service.mapper.JupiterUserRoleMapper;
import org.jupiter.blog.service.service.JupiterUserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class JupiterUserRoleServiceImpl implements JupiterUserRoleService {

	@Autowired
	private JupiterUserRoleMapper userRoleMapper;

	@Autowired
	private JupiterUserRoleStructConvertor jupiterUserRoleStructConvertor;

	@Override
	public JupiterUserRoleDTO getById(String uuid) {
		JupiterUserRole userRole = userRoleMapper.selectByUuid(uuid);
		return jupiterUserRoleStructConvertor.toDto(userRole);
	}

	@Override
	public List<JupiterUserRoleDTO> getAll() {
		List<JupiterUserRole> userRoles = userRoleMapper.selectAll();
		return userRoles.stream()
				.map(jupiterUserRoleStructConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	public List<String> getByUserId(String userId) {
		List<JupiterUserRole> userRoles = userRoleMapper.selectByUserUuid(userId);
		return userRoles.stream()
				.map(JupiterUserRole::getRoleUuid)
				.collect(Collectors.toList());
	}

	@Override
	public List<JupiterUserRoleDTO> getByRoleId(String roleId) {
		List<JupiterUserRole> userRoles = userRoleMapper.selectByRoleId(roleId);
		return userRoles.stream()
				.map(jupiterUserRoleStructConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional
	public void create(JupiterUserRoleDTO dto) {
		JupiterUserRole userRole = jupiterUserRoleStructConvertor.toEntity(dto);
		if (!StringUtils.hasText(userRole.getUuid())){
			userRole.setUuid(UUID.randomUUID().toString());
		}
		userRole.setCreateTime(LocalDateTime.now());
		userRole.setUpdateTime(LocalDateTime.now());
		userRoleMapper.insert(userRole);
	}

	@Override
	@Transactional
	public void update(JupiterUserRoleDTO dto) {
		JupiterUserRole userRole = jupiterUserRoleStructConvertor.toEntity(dto);
		userRole.setUpdateTime(LocalDateTime.now());
		userRoleMapper.updateByUuidSelective(userRole);
	}

	@Override
	@Transactional
	public void delete(String uuid) {
		userRoleMapper.deleteByUuid(uuid);
	}

	@Override
	@Transactional
	public void deleteByUserId(String userId) {
		userRoleMapper.deleteByUserUuid(userId);
	}

	@Override
	@Transactional
	public void deleteByRoleId(String roleId) {
		userRoleMapper.deleteByRoleUuid(roleId);
	}

	@Override
	@Transactional
	public void assignRolesToUser(String userId, List<String> roleIds) {
		// 先删除用户的所有角色
		userRoleMapper.deleteByUserUuid(userId);

		if (CollectionUtils.isEmpty(roleIds)){
			return;
		}

		List<JupiterUserRole> userRoles = roleIds.stream().map(roleId -> {
			JupiterUserRole userRole = new JupiterUserRole();
			userRole.setUuid(UUID.randomUUID().toString());
			userRole.setUserUuid(userId);
			userRole.setRoleUuid(roleId);
			userRole.setCreateTime(LocalDateTime.now());
			userRole.setUpdateTime(LocalDateTime.now());
			return userRole;
		}).toList();

		userRoleMapper.insertBatch(userRoles);
	}

	@Override
	@Transactional
	public void assignUsersToRole(String roleId, List<String> userIds) {
		// 先删除角色的所有用户
		userRoleMapper.deleteByRoleUuid(roleId);

		// 重新分配用户
		for (String userId : userIds){
			JupiterUserRole userRole = new JupiterUserRole();
			userRole.setUuid(UUID.randomUUID().toString());
			userRole.setUserUuid(userId);
			userRole.setRoleUuid(roleId);
			userRole.setCreateTime(LocalDateTime.now());
			userRole.setUpdateTime(LocalDateTime.now());
			userRoleMapper.insert(userRole);
		}
	}
}
